package com.zc.manager.network.domain;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import com.zc.component.network.core.NetworkProperties;
import com.zc.component.network.core.NetworkType;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.collections4.CollectionUtils;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 网络组件对象 iot_network_config
 *
 * @author wangjibao
 * @date 2022-10-19
 */
@Getter
@Setter
@ToString
public class IotNetworkConfig extends BaseEntity {

    /** 启动 */
    public static final String ENABLED = "enabled";
    /** 禁用 */
    public static final String DISABLED = "disabled";

    // MQTT服务
    public static final String MQTT_SERVER = "MQTT_SERVER";
    // MQTT客户端
    public static final String MQTT_CLIENT = "MQTT_CLIENT";
    // TCP服务
    public static final String TCP_SERVER = "TCP_SERVER";
    // TCP客户端
    public static final String TCP_CLIENT = "TCP_CLIENT";

    /** 主键 */
    private Long id;

    /** 配置项 */
    @Excel(name = "配置项")
    @Size(max = 1000, message = "其他配置长度不能超过1000个字符")
    private String configuration;

    /** 组件名称 */
    @Excel(name = "组件名称")
    @NotBlank(message = "组件名称不能为空")
    @Size(max = 30, message = "组件名称长度不能超过30个字符")
    private String name;

    /** 组件状态 */
    @Excel(name = "组件状态")
    private String startState;

    /** 描述 */
    @Excel(name = "组件描述")
    @Size(max = 500, message = "描述不能超过500个字符")
    private String description;

    /** 类型 */
    @Excel(name = "组件类型")
    private String type;

    @Excel(name = "集群是否共享配置")
    private Boolean shareCluster;

    @Excel(name = "集群配置")
    private String cluster;

    public Optional<Map<String, Object>> getConfig(String serverId) {

        List<Configuration> clusterList = new Gson().fromJson(cluster, new TypeToken<List<Configuration>>() {}.getType());

        if ((Boolean.FALSE.equals(shareCluster)) && CollectionUtils.isNotEmpty(clusterList)) {
            return clusterList.stream()
                    .filter(conf -> serverId.equals(conf.serverId))
                    .findAny()
                    .map(Configuration::getConfiguration);
        }
        return Optional.of(JSONObject.parseObject(configuration));
    }

    public NetworkType lookupNetworkType() {
        return NetworkType.lookup(type).orElseGet(() -> NetworkType.of(type));
    }


    public NetworkProperties toNetworkProperties() {
        NetworkProperties properties = new NetworkProperties();
        properties.setConfigurations(JSONObject.parseObject(configuration));
        properties.setEnabled(ENABLED.equals(startState));
        properties.setId(String.valueOf(getId()));
        properties.setName(name);
        return properties;
    }

    @Getter
    @Setter
    public static class Configuration implements Serializable {
        private String serverId;

        private Map<String, Object> configuration;
    }


}
